import sys import subprocess import py import cffi.pkgconfig as pkgconfig from cffi import PkgConfigError def mock_call(libname, flag): assert libname=="foobarbaz" flags = { "--cflags": "-I/usr/include/python3.6m -DABCD -DCFFI_TEST=1 -O42\n", "--libs": "-L/usr/lib64 -lpython3.6 -shared\n", } return flags[flag] def test_merge_flags(): d1 = {"ham": [1, 2, 3], "spam" : ["a", "b", "c"], "foo" : []} d2 = {"spam" : ["spam", "spam", "spam"], "bar" : ["b", "a", "z"]} pkgconfig.merge_flags(d1, d2) assert d1 == { "ham": [1, 2, 3], "spam" : ["a", "b", "c", "spam", "spam", "spam"], "bar" : ["b", "a", "z"], "foo" : []} def test_pkgconfig(): assert pkgconfig.flags_from_pkgconfig([]) == {} saved = pkgconfig.call try: pkgconfig.call = mock_call flags = pkgconfig.flags_from_pkgconfig(["foobarbaz"]) finally: pkgconfig.call = saved assert flags == { 'include_dirs': ['/usr/include/python3.6m'], 'library_dirs': ['/usr/lib64'], 'libraries': ['python3.6'], 'define_macros': [('ABCD', None), ('CFFI_TEST', '1')], 'extra_compile_args': ['-O42'], 'extra_link_args': ['-shared'] } class mock_subprocess: PIPE = Ellipsis class Popen: def __init__(self, cmd, stdout, stderr): if mock_subprocess.RESULT is None: raise OSError("oops can't run") assert cmd == ['pkg-config', '--print-errors', '--cflags', 'libfoo'] def communicate(self): bout, berr, rc = mock_subprocess.RESULT self.returncode = rc return bout, berr def test_call(): saved = pkgconfig.subprocess try: pkgconfig.subprocess = mock_subprocess mock_subprocess.RESULT = None e = py.test.raises(PkgConfigError, pkgconfig.call, "libfoo", "--cflags") assert str(e.value) == "cannot run pkg-config: oops can't run" mock_subprocess.RESULT = b"", "Foo error!\n", 1 e = py.test.raises(PkgConfigError, pkgconfig.call, "libfoo", "--cflags") assert str(e.value) == "Foo error!" mock_subprocess.RESULT = b"abc\\def\n", "", 0 e = py.test.raises(PkgConfigError, pkgconfig.call, "libfoo", "--cflags") assert str(e.value).startswith("pkg-config --cflags libfoo returned an " "unsupported backslash-escaped output:") mock_subprocess.RESULT = b"abc def\n", "", 0 result = pkgconfig.call("libfoo", "--cflags") assert result == "abc def\n" mock_subprocess.RESULT = b"abc def\n", "", 0 result = pkgconfig.call("libfoo", "--cflags") assert result == "abc def\n" if sys.version_info >= (3,): mock_subprocess.RESULT = b"\xff\n", "", 0 e = py.test.raises(PkgConfigError, pkgconfig.call, "libfoo", "--cflags", encoding="utf-8") assert str(e.value) == ( "pkg-config --cflags libfoo returned bytes that cannot be " "decoded with encoding 'utf-8':\nb'\\xff\\n'") finally: pkgconfig.subprocess = saved