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: 's avatarJuliana Oliveira Rodrigues <juliana.orod@gmail.com>
parent 85998730
......@@ -19,6 +19,7 @@
import pytest
import os.path
import subprocess
from diffoscope.config import Config
from diffoscope.comparators.elf import ElfFile, StaticLibFile
......@@ -29,12 +30,22 @@ from diffoscope.comparators.utils.specialize import specialize
from ..utils.data import data, load_fixture, get_data
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')
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):
assert isinstance(obj1, ElfFile)
......@@ -50,6 +61,7 @@ def obj_differences(obj1, obj2):
@skip_unless_tools_exist('readelf')
@skip_if_tool_version_is('readelf', readelf_version, '2.29')
@skip_if_binutils_does_not_support_x86()
def test_obj_compare_non_existing(monkeypatch, obj1):
monkeypatch.setattr(Config(), 'new_file', True)
......@@ -59,6 +71,7 @@ def test_obj_compare_non_existing(monkeypatch, obj1):
@skip_unless_tools_exist('readelf')
@skip_if_tool_version_is('readelf', readelf_version, '2.29')
@skip_if_binutils_does_not_support_x86()
def test_diff(obj_differences):
assert len(obj_differences) == 1
......@@ -95,6 +108,7 @@ def lib_differences(lib1, lib2):
@skip_unless_tools_exist('readelf', 'objdump')
@skip_if_tool_version_is('readelf', readelf_version, '2.29')
@skip_if_binutils_does_not_support_x86()
def test_lib_differences(lib_differences):
assert len(lib_differences) == 2
......@@ -107,6 +121,7 @@ def test_lib_differences(lib_differences):
@skip_unless_tools_exist('readelf', 'objdump')
@skip_if_tool_version_is('readelf', readelf_version, '2.29')
@skip_if_binutils_does_not_support_x86()
def test_lib_compare_non_existing(monkeypatch, lib1):
monkeypatch.setattr(Config(), 'new_file', True)
......
......@@ -37,6 +37,15 @@ def skip_unless_tools_exist(*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):
if tools_missing(tool):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment