Bug#851588: diffoscope: skip tests if binutils can't handle the object file format

Daniel Shahaf danielsh at apache.org
Mon Jan 16 19:07:57 UTC 2017

Mattia Rizzolo wrote on Mon, Jan 16, 2017 at 18:06:48 +0100:
> So, I finally managed to look into the tests failures were have been
> seeing in ubuntu's autopkgtest in armhf (and probably also ppc64el and
> s390x, but I didn't test for that).
> As supposed, the reason is that we're trying to disassemble x86-64
> binaries, and the installed multiarch can't deal with them;

Then should we look for 'x86_64-linux-gnu-readelf' rather than bare
'readelf'?  And likewise for 'objdump' and friends.

> Now, I came up with a patch, but my python foo has its limit, and I
> think somebody might improve it quite some (e.g. please tell me how I
> can write a decorated fuction that doesn't take any value as input and
> still returns only pytest.mark.skipif()... what I did is uglyugly), so
> I'm filing it as a bug here instead of committing; see the attachment :)

The expression after the "@" sign is evaluated; that should result in
a callable object, which is called with the decoratee as an argument.
In your case, you should be able to pass no parameters, e.g.,
and then delete the sole formal argument from the function definition.

Note that the parentheses are still required in this case, since the
thing that is called with 'test_obj_compare_non_existing' as an actual
parameter is not 'skip_if_binutils_do_not_support_x86' but rather the
function it returns.

I'm not sure what's the best way to combine skip_unless_tools_exist and
pytest.mark.skipif().  The way decorators work is that they're invoked
on each other's return values, i.e.,
    def skip_if_binutils_do_not_support_x86():
        func1 = skip_unless_tools_exist('objdump')
        func2 = pytest.mark.skipif(...)
        return (lambda func: func2(func1(func)))
but whether that's readable is a question of taste.



>      return obj1.compare(obj2).details
>  @skip_unless_tools_exist('readelf')
> + at skip_if_binutils_do_not_support_x86(True)
>  def test_obj_compare_non_existing(monkeypatch, obj1):
>      monkeypatch.setattr(Config(), 'new_file', True)
>      difference = obj1.compare(MissingFile('/nonexisting', obj1))

> +def skip_if_binutils_do_not_support_x86(func):
> +    if tools_missing('objdump'):
> +         return skip_unless_tools_exists('objdump')
> +    out = subprocess.check_output(('objdump', '-i')).decode('utf-8').splitlines()
> +    return pytest.mark.skipif(
> +        'elf64-x86-64' not in out,
> +        reason="requires a binutils capable of reading x86-64 binaries"
> +    )
> +
>  def load_fixture(filename):
>      return pytest.fixture(
>          lambda: specialize(FilesystemFile(filename))
> -- 
> 2.11.0

More information about the Reproducible-builds mailing list