| #!/usr/bin/env fuchsia-vendored-python |
| # Copyright 2023 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import shutil |
| import tempfile |
| import unittest |
| import os |
| |
| from build_id_conv import main, touch |
| |
| |
| # Tests reading and writing ids.txt files. |
| class TestIdsTxt(unittest.TestCase): |
| def setUp(self): |
| # Create a temporary directory. |
| self.test_dir = tempfile.mkdtemp() |
| |
| # Create a subdirectory in it and write some placeholder symbol files in it. |
| self.sofiles_dir = os.path.join(self.test_dir, "sofiles_dir") |
| os.mkdir(self.sofiles_dir) |
| touch(os.path.join(self.sofiles_dir, "foo.so")) |
| touch(os.path.join(self.sofiles_dir, "bar.so")) |
| |
| def tearDown(self): |
| shutil.rmtree(self.test_dir) |
| |
| # Tests reading/writing ids.txt files without explicit reference input/output directories: |
| # - paths read from the input file should be interpreted as relative to its directory |
| # - paths written in the output file should be absolute |
| def test_read_and_write(self): |
| input_path = os.path.join(self.test_dir, "input-ids.txt") |
| output_path = os.path.join(self.test_dir, "output-ids.txt") |
| with open(input_path, mode="wt") as input_file: |
| input_file.write("12345678 sofiles_dir/foo.so\n") |
| input_file.write("abcdef00 sofiles_dir/bar.so\n") |
| |
| main( |
| [ |
| "--input", |
| os.path.relpath(input_path), |
| "--output-format", |
| "ids.txt", |
| os.path.relpath(output_path), |
| ] |
| ) |
| with open(output_path, mode="rt") as output_file: |
| self.assertSequenceEqual( |
| output_file.readlines(), |
| [ |
| "12345678 %s\n" % os.path.join(self.sofiles_dir, "foo.so"), |
| "abcdef00 %s\n" % os.path.join(self.sofiles_dir, "bar.so"), |
| ], |
| ) |
| |
| # Tests that input paths are expanded correctly if a reference input directory is given. |
| def test_read_with_rel_in(self): |
| input_path = os.path.join(self.test_dir, "input-ids.txt") |
| output_path = os.path.join(self.test_dir, "output-ids.txt") |
| with open(input_path, mode="wt") as input_file: |
| input_file.write("12345678 foo.so\n") |
| input_file.write("abcdef00 bar.so\n") |
| |
| main( |
| [ |
| "--input", |
| os.path.relpath(input_path), |
| "--ids-rel-to-in", |
| os.path.relpath(self.sofiles_dir), |
| "--output-format", |
| "ids.txt", |
| os.path.relpath(output_path), |
| ] |
| ) |
| with open(output_path, mode="rt") as output_file: |
| self.assertSequenceEqual( |
| output_file.readlines(), |
| [ |
| "12345678 %s\n" % os.path.join(self.sofiles_dir, "foo.so"), |
| "abcdef00 %s\n" % os.path.join(self.sofiles_dir, "bar.so"), |
| ], |
| ) |
| |
| # Tests that output paths are written correctly if a reference output directory is given. |
| def test_write_with_rel_out(self): |
| input_path = os.path.join(self.test_dir, "input-ids.txt") |
| output_path = os.path.join(self.test_dir, "output-ids.txt") |
| with open(input_path, mode="wt") as input_file: |
| input_file.write("12345678 sofiles_dir/foo.so\n") |
| input_file.write("abcdef00 sofiles_dir/bar.so\n") |
| |
| main( |
| [ |
| "--input", |
| os.path.relpath(input_path), |
| "--ids-rel-to-out", |
| os.path.relpath(self.sofiles_dir), |
| "--output-format", |
| "ids.txt", |
| os.path.relpath(output_path), |
| ] |
| ) |
| with open(output_path, mode="rt") as output_file: |
| self.assertSequenceEqual( |
| output_file.readlines(), |
| [ |
| "12345678 foo.so\n", |
| "abcdef00 bar.so\n", |
| ], |
| ) |
| |
| |
| # Tests reading and writing .build-id directories. |
| class TestBuildId(unittest.TestCase): |
| def setUp(self): |
| # Create a temporary directory. |
| self.test_dir = tempfile.mkdtemp() |
| |
| # Create a subdirectory in it and write some placeholder symbol files in it. |
| self.input_dir = os.path.join(self.test_dir, "input-build-id-dir") |
| os.makedirs(os.path.join(self.input_dir, "12")) |
| with open( |
| os.path.join(self.input_dir, "12/345678.debug"), mode="wt" |
| ) as symbol_file: |
| symbol_file.write("foo") |
| os.makedirs(os.path.join(self.input_dir, "ab")) |
| with open( |
| os.path.join(self.input_dir, "ab/cdef00.debug"), mode="wt" |
| ) as symbol_file: |
| symbol_file.write("bar") |
| |
| def tearDown(self): |
| shutil.rmtree(self.test_dir) |
| |
| # Tests converting a .build-id directory into another .build-id directory containing hard links. |
| def test_read_and_write_with_hardlinks(self): |
| output_dir = os.path.join(self.test_dir, "output-build-id-dir") |
| |
| main( |
| [ |
| "--input", |
| os.path.relpath(self.input_dir), |
| "--output-format", |
| ".build-id", |
| os.path.relpath(output_dir), |
| ] |
| ) |
| self.assertTrue( |
| os.path.isfile(os.path.join(output_dir, "12/345678.debug")) |
| ) |
| with open( |
| os.path.join(output_dir, "12/345678.debug"), mode="rt" |
| ) as symbol_file: |
| self.assertEqual(symbol_file.read(), "foo") |
| self.assertTrue( |
| os.path.isfile(os.path.join(output_dir, "ab/cdef00.debug")) |
| ) |
| with open( |
| os.path.join(output_dir, "ab/cdef00.debug"), mode="rt" |
| ) as symbol_file: |
| self.assertEqual(symbol_file.read(), "bar") |
| |
| # Tests converting a .build-id directory into another .build-id directory containing symlinks. |
| def test_read_and_write_with_symlinks(self): |
| output_dir = os.path.join(self.test_dir, "output-build-id-dir") |
| |
| main( |
| [ |
| "--input", |
| os.path.relpath(self.input_dir), |
| "--output-format", |
| ".build-id", |
| "--build-id-mode", |
| "symlink", |
| os.path.relpath(output_dir), |
| ] |
| ) |
| self.assertEqual( |
| os.readlink(os.path.join(output_dir, "12/345678.debug")), |
| os.path.join(self.input_dir, "12/345678.debug"), |
| ) |
| self.assertEqual( |
| os.readlink(os.path.join(output_dir, "ab/cdef00.debug")), |
| os.path.join(self.input_dir, "ab/cdef00.debug"), |
| ) |
| |
| |
| # Tests converting between ids.txt files and .build-id directories. |
| class TestConversion(unittest.TestCase): |
| def test_from_ids_txt_to_build_id_dir(self): |
| with tempfile.TemporaryDirectory() as test_dir: |
| # Create an ids.txt file and placeholder symbols files. |
| input_path = os.path.join(test_dir, "input-ids.txt") |
| with open(input_path, mode="wt") as input_file: |
| input_file.write("12345678 foo.so\n") |
| input_file.write("abcdef00 bar.so\n") |
| touch(os.path.join(test_dir, "foo.so")) |
| touch(os.path.join(test_dir, "bar.so")) |
| |
| # Convert into a .build-id directory and verify. |
| output_dir = os.path.join(test_dir, "output-build-id-dir") |
| main( |
| [ |
| "--input", |
| os.path.relpath(input_path), |
| os.path.relpath(output_dir), |
| ] |
| ) |
| self.assertTrue( |
| os.path.isfile(os.path.join(output_dir, "12/345678.debug")) |
| ) |
| self.assertTrue( |
| os.path.isfile(os.path.join(output_dir, "ab/cdef00.debug")) |
| ) |
| |
| def test_from_build_id_dir_to_ids_txt(self): |
| with tempfile.TemporaryDirectory() as test_dir: |
| # Create a .build-id directory with placeholder symbols files in it. |
| input_dir = os.path.join(test_dir, "input-build-id-dir") |
| os.makedirs(os.path.join(input_dir, "12")) |
| touch(os.path.join(input_dir, "12/345678.debug")) |
| os.makedirs(os.path.join(input_dir, "ab")) |
| touch(os.path.join(input_dir, "ab/cdef00.debug")) |
| |
| # Convert into an ids.txt file and verify. |
| output_path = os.path.join(test_dir, "output-ids.txt") |
| main( |
| [ |
| "--input", |
| os.path.relpath(input_dir), |
| os.path.relpath(output_path), |
| ] |
| ) |
| with open(output_path, mode="rt") as output_file: |
| self.assertSequenceEqual( |
| output_file.readlines(), |
| [ |
| "12345678 %s\n" |
| % os.path.join(input_dir, "12/345678.debug"), |
| "abcdef00 %s\n" |
| % os.path.join(input_dir, "ab/cdef00.debug"), |
| ], |
| ) |
| |
| |
| if __name__ == "__main__": |
| unittest.main() |