From b922360a46c32f5781cfcd7705bd3d8426e4edf1 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Wed, 28 Dec 2011 10:06:55 +0200 Subject: [PATCH] initial version of example tests --- examples/reference_output/dwarf_die_tree.out | 62 +++++++++++++ .../reference_output/dwarf_location_lists.out | 23 +++++ .../reference_output/elf_low_high_api.out | 9 ++ examples/reference_output/elf_relocations.out | 9 ++ .../elf_show_debug_sections.out | 10 +++ .../elfclass_address_size.out | 5 ++ .../reference_output/examine_dwarf_info.out | 13 +++ test/run_all_unittests.py | 2 +- test/run_examples_test.py | 86 +++++++++++++++++++ test/run_readelf_tests.py | 25 ++---- test/utils.py | 24 +++++- 11 files changed, 247 insertions(+), 21 deletions(-) create mode 100644 examples/reference_output/dwarf_die_tree.out create mode 100644 examples/reference_output/dwarf_location_lists.out create mode 100644 examples/reference_output/elf_low_high_api.out create mode 100644 examples/reference_output/elf_relocations.out create mode 100644 examples/reference_output/elf_show_debug_sections.out create mode 100644 examples/reference_output/elfclass_address_size.out create mode 100644 examples/reference_output/examine_dwarf_info.out create mode 100755 test/run_examples_test.py diff --git a/examples/reference_output/dwarf_die_tree.out b/examples/reference_output/dwarf_die_tree.out new file mode 100644 index 0000000..143cbbb --- /dev/null +++ b/examples/reference_output/dwarf_die_tree.out @@ -0,0 +1,62 @@ +Processing file: ./examples/sample_exe64.elf + Found a compile unit at offset 0, length 115 + Top DIE with tag=DW_TAG_compile_unit + name=../sysdeps/x86_64/elf/start.S + DIE tag=DW_TAG_compile_unit + Found a compile unit at offset 119, length 135 + Top DIE with tag=DW_TAG_compile_unit + name=init.c + DIE tag=DW_TAG_compile_unit + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_variable + DIE tag=DW_TAG_const_type + Found a compile unit at offset 258, length 156 + Top DIE with tag=DW_TAG_compile_unit + name=z.c + DIE tag=DW_TAG_compile_unit + DIE tag=DW_TAG_subprogram + DIE tag=DW_TAG_formal_parameter + DIE tag=DW_TAG_formal_parameter + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_pointer_type + DIE tag=DW_TAG_pointer_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_variable + Found a compile unit at offset 418, length 300 + Top DIE with tag=DW_TAG_compile_unit + name=elf-init.c + DIE tag=DW_TAG_compile_unit + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_typedef + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_subprogram + DIE tag=DW_TAG_subprogram + DIE tag=DW_TAG_formal_parameter + DIE tag=DW_TAG_formal_parameter + DIE tag=DW_TAG_formal_parameter + DIE tag=DW_TAG_variable + DIE tag=DW_TAG_lexical_block + DIE tag=DW_TAG_variable + DIE tag=DW_TAG_pointer_type + DIE tag=DW_TAG_pointer_type + DIE tag=DW_TAG_base_type + DIE tag=DW_TAG_const_type + DIE tag=DW_TAG_array_type + DIE tag=DW_TAG_subrange_type + DIE tag=DW_TAG_subroutine_type + DIE tag=DW_TAG_formal_parameter + DIE tag=DW_TAG_formal_parameter + DIE tag=DW_TAG_formal_parameter + DIE tag=DW_TAG_pointer_type + DIE tag=DW_TAG_variable + DIE tag=DW_TAG_variable diff --git a/examples/reference_output/dwarf_location_lists.out b/examples/reference_output/dwarf_location_lists.out new file mode 100644 index 0000000..8788755 --- /dev/null +++ b/examples/reference_output/dwarf_location_lists.out @@ -0,0 +1,23 @@ +Processing file: ./examples/sample_exe64.elf + Found a compile unit at offset 0, length 115 + Found a compile unit at offset 119, length 135 + Found a compile unit at offset 258, length 156 + DIE DW_TAG_subprogram. attr DW_AT_frame_base. + LocationEntry(begin_offset=0, end_offset=1, loc_expr=[119, 8]) <<(DW_OP_breg7 (rsp): 8)>> + LocationEntry(begin_offset=1, end_offset=4, loc_expr=[119, 16]) <<(DW_OP_breg7 (rsp): 16)>> + LocationEntry(begin_offset=4, end_offset=43, loc_expr=[118, 16]) <<(DW_OP_breg6 (rbp): 16)>> + Found a compile unit at offset 418, length 300 + DIE DW_TAG_subprogram. attr DW_AT_frame_base. + LocationEntry(begin_offset=16, end_offset=64, loc_expr=[119, 8]) <<(DW_OP_breg7 (rsp): 8)>> + LocationEntry(begin_offset=64, end_offset=153, loc_expr=[119, 192, 0]) <<(DW_OP_breg7 (rsp): 64)>> + DIE DW_TAG_formal_parameter. attr DW_AT_location. + LocationEntry(begin_offset=16, end_offset=85, loc_expr=[85]) <<(DW_OP_reg5 (rdi))>> + LocationEntry(begin_offset=85, end_offset=143, loc_expr=[94]) <<(DW_OP_reg14 (r14))>> + DIE DW_TAG_formal_parameter. attr DW_AT_location. + LocationEntry(begin_offset=16, end_offset=85, loc_expr=[84]) <<(DW_OP_reg4 (rsi))>> + LocationEntry(begin_offset=85, end_offset=138, loc_expr=[93]) <<(DW_OP_reg13 (r13))>> + DIE DW_TAG_formal_parameter. attr DW_AT_location. + LocationEntry(begin_offset=16, end_offset=85, loc_expr=[81]) <<(DW_OP_reg1 (rdx))>> + LocationEntry(begin_offset=85, end_offset=133, loc_expr=[92]) <<(DW_OP_reg12 (r12))>> + DIE DW_TAG_variable. attr DW_AT_location. + LocationEntry(begin_offset=92, end_offset=123, loc_expr=[83]) <<(DW_OP_reg3 (rbx))>> diff --git a/examples/reference_output/elf_low_high_api.out b/examples/reference_output/elf_low_high_api.out new file mode 100644 index 0000000..b808199 --- /dev/null +++ b/examples/reference_output/elf_low_high_api.out @@ -0,0 +1,9 @@ +Processing file: ./examples/sample_exe64.elf +Low level API... + 42 sections + Section name: 1, type: SHT_SYMTAB +High level API... + 42 sections + Section name: .symtab, type: SHT_SYMTAB + It's a symbol section with 80 symbols + The name of symbol #60 is: __init_array_start diff --git a/examples/reference_output/elf_relocations.out b/examples/reference_output/elf_relocations.out new file mode 100644 index 0000000..41bb576 --- /dev/null +++ b/examples/reference_output/elf_relocations.out @@ -0,0 +1,9 @@ +Processing file: ./examples/sample_exe64.elf + .rela.dyn section with 1 relocations + + offset = 6295520 diff --git a/examples/reference_output/elf_show_debug_sections.out b/examples/reference_output/elf_show_debug_sections.out new file mode 100644 index 0000000..d27b255 --- /dev/null +++ b/examples/reference_output/elf_show_debug_sections.out @@ -0,0 +1,10 @@ +In file: ./examples/sample_exe64.elf + .debug_aranges + .debug_pubnames + .debug_info + .debug_abbrev + .debug_line + .debug_frame + .debug_str + .debug_loc + .debug_ranges diff --git a/examples/reference_output/elfclass_address_size.out b/examples/reference_output/elfclass_address_size.out new file mode 100644 index 0000000..4dcdb1f --- /dev/null +++ b/examples/reference_output/elfclass_address_size.out @@ -0,0 +1,5 @@ +./examples/sample_exe64.elf: elfclass is 64 + CU at offset 0x0. address_size is 8 + CU at offset 0x77. address_size is 8 + CU at offset 0x102. address_size is 8 + CU at offset 0x1a2. address_size is 8 diff --git a/examples/reference_output/examine_dwarf_info.out b/examples/reference_output/examine_dwarf_info.out new file mode 100644 index 0000000..968be29 --- /dev/null +++ b/examples/reference_output/examine_dwarf_info.out @@ -0,0 +1,13 @@ +Processing file: ./examples/sample_exe64.elf + Found a compile unit at offset 0, length 115 + Top DIE with tag=DW_TAG_compile_unit + name=../sysdeps/x86_64/elf/start.S + Found a compile unit at offset 119, length 135 + Top DIE with tag=DW_TAG_compile_unit + name=init.c + Found a compile unit at offset 258, length 156 + Top DIE with tag=DW_TAG_compile_unit + name=z.c + Found a compile unit at offset 418, length 300 + Top DIE with tag=DW_TAG_compile_unit + name=elf-init.c diff --git a/test/run_all_unittests.py b/test/run_all_unittests.py index 100744a..e1a62f2 100755 --- a/test/run_all_unittests.py +++ b/test/run_all_unittests.py @@ -1,6 +1,6 @@ #!/usr/bin/env python #------------------------------------------------------------------------------- -# tests/run_all_unittests.py +# test/run_all_unittests.py # # Run all unit tests (alternative to running 'python -m unittest discover ...') # diff --git a/test/run_examples_test.py b/test/run_examples_test.py new file mode 100755 index 0000000..4a73b99 --- /dev/null +++ b/test/run_examples_test.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +#------------------------------------------------------------------------------- +# test/run_examples_test.py +# +# Run the examples and compare their output to a reference +# +# Eli Bendersky (eliben@gmail.com) +# This code is in the public domain +#------------------------------------------------------------------------------- +import os, sys +import logging +sys.path.insert(0, '.') +from test.utils import run_exe, is_in_rootdir, dump_output_to_temp_files + + +# Create a global logger object +# +testlog = logging.getLogger('run_examples_test') +testlog.setLevel(logging.DEBUG) +testlog.addHandler(logging.StreamHandler(sys.stdout)) + + +def discover_examples(): + """ Return paths to all example scripts. Assume we're in the root source + dir of pyelftools. + """ + root = './examples' + for filename in os.listdir(root): + if os.path.splitext(filename)[1] == '.py': + yield os.path.join(root, filename) + + +def reference_output_path(example_path): + """ Compute the reference output path from a given example path. + """ + examples_root, example_name = os.path.split(example_path) + example_noext, _ = os.path.splitext(example_name) + return os.path.join(examples_root, 'reference_output', example_noext + '.out') + + +def run_example_and_compare(example_path): + testlog.info("Example '%s'" % example_path) + + reference_path = reference_output_path(example_path) + ref_str = '' + try: + with open(reference_path) as ref_f: + ref_str = ref_f.read() + except (IOError, OSError) as e: + testlog.info('.......ERROR - reference output cannot be read! - %s' % e) + return False + + rc, example_out = run_exe(example_path, ['./examples/sample_exe64.elf']) + if rc != 0: + testlog.info('.......ERROR - example returned error code %s' % rc) + return False + + if example_out == ref_str: + return True + else: + testlog.info('.......FAIL comparison') + dump_output_to_temp_files(testlog, example_out) + return False + + +def main(): + if not is_in_rootdir(): + testlog.error('Error: Please run me from the root dir of pyelftools!') + return 1 + + success = True + for example_path in discover_examples(): + if success: + success = success and run_example_and_compare(example_path) + + if success: + testlog.info('\nConclusion: SUCCESS') + return 0 + else: + testlog.info('\nConclusion: FAIL') + return 1 + + +if __name__ == '__main__': + sys.exit(main()) + diff --git a/test/run_readelf_tests.py b/test/run_readelf_tests.py index 9ffa519..984b7a5 100755 --- a/test/run_readelf_tests.py +++ b/test/run_readelf_tests.py @@ -1,6 +1,6 @@ #!/usr/bin/env python #------------------------------------------------------------------------------- -# tests/run_readelf_tests.py +# test/run_readelf_tests.py # # Automatic test runner for elftools & readelf # @@ -12,9 +12,9 @@ import re from difflib import SequenceMatcher from optparse import OptionParser import logging -import tempfile import platform -from test.utils import run_exe, is_in_rootdir +sys.path.insert(0, '.') # to load *our* test, not Python's test +from test.utils import run_exe, is_in_rootdir, dump_output_to_temp_files # Create a global logger object @@ -65,7 +65,7 @@ def run_test_on_file(filename, verbose=False): testlog.info('.......................FAIL') testlog.info('....for option "%s"' % option) testlog.info('@@ ' + errmsg) - dump_output_to_temp_files(*stdouts) + dump_output_to_temp_files(testlog, *stdouts) return success @@ -144,21 +144,7 @@ def compare_output(s1, s2): i, lines1[i], lines2[i]) return False, errmsg return True, '' - -def dump_output_to_temp_files(*args): - """ Dumps the output strings given in 'args' to temp files: one for each - arg. - """ - for i, s in enumerate(args): - fd, path = tempfile.mkstemp( - prefix='out' + str(i + 1) + '_', - suffix='.stdout') - file = os.fdopen(fd, 'w') - file.write(s) - file.close() - testlog.info('@@ Output #%s dumped to file: %s' % (i + 1, path)) - def main(): if not is_in_rootdir(): @@ -187,7 +173,8 @@ def main(): success = True for filename in filenames: - success = success and run_test_on_file( + if success: + success = success and run_test_on_file( filename, verbose=options.verbose) diff --git a/test/utils.py b/test/utils.py index e09521c..803a999 100644 --- a/test/utils.py +++ b/test/utils.py @@ -1,4 +1,12 @@ -import os, subprocess +#------------------------------------------------------------------------------- +# test/utils.py +# +# Some common utils for tests +# +# Eli Bendersky (eliben@gmail.com) +# This code is in the public domain +#------------------------------------------------------------------------------- +import os, subprocess, tempfile def run_exe(exe_path, args): @@ -20,3 +28,17 @@ def is_in_rootdir(): dirstuff = os.listdir('.') return 'test' in dirstuff and 'elftools' in dirstuff + +def dump_output_to_temp_files(testlog, *args): + """ Dumps the output strings given in 'args' to temp files: one for each + arg. + """ + for i, s in enumerate(args): + fd, path = tempfile.mkstemp( + prefix='out' + str(i + 1) + '_', + suffix='.stdout') + file = os.fdopen(fd, 'w') + file.write(s) + file.close() + testlog.info('@@ Output #%s dumped to file: %s' % (i + 1, path)) + -- 2.30.2