Skip to content
Snippets Groups Projects
Commit 9e2013fe authored by Juliana Oliveira Rodrigues's avatar Juliana Oliveira Rodrigues
Browse files

tests: test_elf: fixed readelf exit code 1


Due to a recent code change in readelf, when no section was found,
readelf returned code 1 instead of the previous code 0. This behaviour
change caused diffoscope to not append details whenever a section wasn't
found, including in our own tests.

The modification was made in version 2.29 of binutils and – although was
quickly fixed in version 2.29.1 – leaves a version hole where diffoscope
might not work as expected without further information.

This patch adds a version checker for readelf where a few tests are
ignored if someone happens to be using binutils 2.29.

For more information on the change:
binutils/readelf.c:get_section_contents

Fixes #877728

Signed-off-by: default avatarJuliana Oliveira Rodrigues <juliana.orod@gmail.com>
parent 85998730
No related branches found
No related tags found
No related merge requests found
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
import pytest import pytest
import os.path import os.path
import subprocess
from diffoscope.config import Config from diffoscope.config import Config
from diffoscope.comparators.elf import ElfFile, StaticLibFile from diffoscope.comparators.elf import ElfFile, StaticLibFile
...@@ -29,12 +30,22 @@ from diffoscope.comparators.utils.specialize import specialize ...@@ -29,12 +30,22 @@ from diffoscope.comparators.utils.specialize import specialize
from ..utils.data import data, load_fixture, get_data from ..utils.data import data, load_fixture, get_data
from ..utils.tools import skip_unless_tools_exist, \ from ..utils.tools import skip_unless_tools_exist, \
skip_if_binutils_does_not_support_x86, skip_unless_module_exists skip_if_binutils_does_not_support_x86, skip_unless_module_exists, \
skip_if_tool_version_is
obj1 = load_fixture('test1.o') obj1 = load_fixture('test1.o')
obj2 = load_fixture('test2.o') obj2 = load_fixture('test2.o')
def readelf_version():
try:
out = subprocess.check_output(['readelf', '--version'])
except subprocess.CalledProcessError as e:
out = e.output
return out.decode('UTF-8').splitlines()[0].split()[-1].strip()
def test_obj_identification(obj1): def test_obj_identification(obj1):
assert isinstance(obj1, ElfFile) assert isinstance(obj1, ElfFile)
...@@ -50,6 +61,7 @@ def obj_differences(obj1, obj2): ...@@ -50,6 +61,7 @@ def obj_differences(obj1, obj2):
@skip_unless_tools_exist('readelf') @skip_unless_tools_exist('readelf')
@skip_if_tool_version_is('readelf', readelf_version, '2.29')
@skip_if_binutils_does_not_support_x86() @skip_if_binutils_does_not_support_x86()
def test_obj_compare_non_existing(monkeypatch, obj1): def test_obj_compare_non_existing(monkeypatch, obj1):
monkeypatch.setattr(Config(), 'new_file', True) monkeypatch.setattr(Config(), 'new_file', True)
...@@ -59,6 +71,7 @@ def test_obj_compare_non_existing(monkeypatch, obj1): ...@@ -59,6 +71,7 @@ def test_obj_compare_non_existing(monkeypatch, obj1):
@skip_unless_tools_exist('readelf') @skip_unless_tools_exist('readelf')
@skip_if_tool_version_is('readelf', readelf_version, '2.29')
@skip_if_binutils_does_not_support_x86() @skip_if_binutils_does_not_support_x86()
def test_diff(obj_differences): def test_diff(obj_differences):
assert len(obj_differences) == 1 assert len(obj_differences) == 1
...@@ -95,6 +108,7 @@ def lib_differences(lib1, lib2): ...@@ -95,6 +108,7 @@ def lib_differences(lib1, lib2):
@skip_unless_tools_exist('readelf', 'objdump') @skip_unless_tools_exist('readelf', 'objdump')
@skip_if_tool_version_is('readelf', readelf_version, '2.29')
@skip_if_binutils_does_not_support_x86() @skip_if_binutils_does_not_support_x86()
def test_lib_differences(lib_differences): def test_lib_differences(lib_differences):
assert len(lib_differences) == 2 assert len(lib_differences) == 2
...@@ -107,6 +121,7 @@ def test_lib_differences(lib_differences): ...@@ -107,6 +121,7 @@ def test_lib_differences(lib_differences):
@skip_unless_tools_exist('readelf', 'objdump') @skip_unless_tools_exist('readelf', 'objdump')
@skip_if_tool_version_is('readelf', readelf_version, '2.29')
@skip_if_binutils_does_not_support_x86() @skip_if_binutils_does_not_support_x86()
def test_lib_compare_non_existing(monkeypatch, lib1): def test_lib_compare_non_existing(monkeypatch, lib1):
monkeypatch.setattr(Config(), 'new_file', True) monkeypatch.setattr(Config(), 'new_file', True)
......
...@@ -37,6 +37,15 @@ def skip_unless_tools_exist(*required): ...@@ -37,6 +37,15 @@ def skip_unless_tools_exist(*required):
reason="requires {}".format(" and ".join(required)), reason="requires {}".format(" and ".join(required)),
) )
def skip_if_tool_version_is(tool, actual_ver, target_ver, vcls=LooseVersion):
if tools_missing(tool):
return pytest.mark.skipif(True, reason="requires {}".format(tool))
if callable(actual_ver):
actual_ver = actual_ver()
return pytest.mark.skipif(
vcls(str(actual_ver)) == vcls(str(target_ver)),
reason="requires {} != {} ({} detected)".format(tool, target_ver, actual_ver)
)
def skip_unless_tool_is_at_least(tool, actual_ver, min_ver, vcls=LooseVersion): def skip_unless_tool_is_at_least(tool, actual_ver, min_ver, vcls=LooseVersion):
if tools_missing(tool): if tools_missing(tool):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment