1import sys 2import subprocess 3import py 4import cffi.pkgconfig as pkgconfig 5from cffi import PkgConfigError 6 7 8def mock_call(libname, flag): 9 assert libname=="foobarbaz" 10 flags = { 11 "--cflags": "-I/usr/include/python3.6m -DABCD -DCFFI_TEST=1 -O42\n", 12 "--libs": "-L/usr/lib64 -lpython3.6 -shared\n", 13 } 14 return flags[flag] 15 16 17def test_merge_flags(): 18 d1 = {"ham": [1, 2, 3], "spam" : ["a", "b", "c"], "foo" : []} 19 d2 = {"spam" : ["spam", "spam", "spam"], "bar" : ["b", "a", "z"]} 20 21 pkgconfig.merge_flags(d1, d2) 22 assert d1 == { 23 "ham": [1, 2, 3], 24 "spam" : ["a", "b", "c", "spam", "spam", "spam"], 25 "bar" : ["b", "a", "z"], 26 "foo" : []} 27 28 29def test_pkgconfig(): 30 assert pkgconfig.flags_from_pkgconfig([]) == {} 31 32 saved = pkgconfig.call 33 try: 34 pkgconfig.call = mock_call 35 flags = pkgconfig.flags_from_pkgconfig(["foobarbaz"]) 36 finally: 37 pkgconfig.call = saved 38 assert flags == { 39 'include_dirs': ['/usr/include/python3.6m'], 40 'library_dirs': ['/usr/lib64'], 41 'libraries': ['python3.6'], 42 'define_macros': [('ABCD', None), ('CFFI_TEST', '1')], 43 'extra_compile_args': ['-O42'], 44 'extra_link_args': ['-shared'] 45 } 46 47class mock_subprocess: 48 PIPE = Ellipsis 49 class Popen: 50 def __init__(self, cmd, stdout, stderr): 51 if mock_subprocess.RESULT is None: 52 raise OSError("oops can't run") 53 assert cmd == ['pkg-config', '--print-errors', '--cflags', 'libfoo'] 54 def communicate(self): 55 bout, berr, rc = mock_subprocess.RESULT 56 self.returncode = rc 57 return bout, berr 58 59def test_call(): 60 saved = pkgconfig.subprocess 61 try: 62 pkgconfig.subprocess = mock_subprocess 63 64 mock_subprocess.RESULT = None 65 e = py.test.raises(PkgConfigError, pkgconfig.call, "libfoo", "--cflags") 66 assert str(e.value) == "cannot run pkg-config: oops can't run" 67 68 mock_subprocess.RESULT = b"", "Foo error!\n", 1 69 e = py.test.raises(PkgConfigError, pkgconfig.call, "libfoo", "--cflags") 70 assert str(e.value) == "Foo error!" 71 72 mock_subprocess.RESULT = b"abc\\def\n", "", 0 73 e = py.test.raises(PkgConfigError, pkgconfig.call, "libfoo", "--cflags") 74 assert str(e.value).startswith("pkg-config --cflags libfoo returned an " 75 "unsupported backslash-escaped output:") 76 77 mock_subprocess.RESULT = b"abc def\n", "", 0 78 result = pkgconfig.call("libfoo", "--cflags") 79 assert result == "abc def\n" 80 81 mock_subprocess.RESULT = b"abc def\n", "", 0 82 result = pkgconfig.call("libfoo", "--cflags") 83 assert result == "abc def\n" 84 85 if sys.version_info >= (3,): 86 mock_subprocess.RESULT = b"\xff\n", "", 0 87 e = py.test.raises(PkgConfigError, pkgconfig.call, 88 "libfoo", "--cflags", encoding="utf-8") 89 assert str(e.value) == ( 90 "pkg-config --cflags libfoo returned bytes that cannot be " 91 "decoded with encoding 'utf-8':\nb'\\xff\\n'") 92 93 finally: 94 pkgconfig.subprocess = saved 95