diff options
author | Armin Rigo <arigo@tunes.org> | 2019-04-26 13:59:13 +0200 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2019-04-26 13:59:13 +0200 |
commit | 027ca7570f39680c02745e428f92a8711bd57642 (patch) | |
tree | 506b5c335363e371e0c14f8465c601a666c967b7 /testing/cffi0 | |
parent | b695f1211931bd04e3e0dddca4b8d8426f68de10 (diff) | |
parent | 4a672063a0c45b5734d1a5137ea14f5fc0c870fe (diff) | |
download | cffi-027ca7570f39680c02745e428f92a8711bd57642.tar.gz |
merge pull request #96. Thanks Cody!
Diffstat (limited to 'testing/cffi0')
-rw-r--r-- | testing/cffi0/backend_tests.py | 109 | ||||
-rw-r--r-- | testing/cffi0/test_ffi_backend.py | 45 | ||||
-rw-r--r-- | testing/cffi0/test_function.py | 4 | ||||
-rw-r--r-- | testing/cffi0/test_ownlib.py | 2 | ||||
-rw-r--r-- | testing/cffi0/test_parsing.py | 36 | ||||
-rw-r--r-- | testing/cffi0/test_verify.py | 24 | ||||
-rw-r--r-- | testing/cffi0/test_zintegration.py | 6 |
7 files changed, 175 insertions, 51 deletions
diff --git a/testing/cffi0/backend_tests.py b/testing/cffi0/backend_tests.py index 13a4c78..7b55ba8 100644 --- a/testing/cffi0/backend_tests.py +++ b/testing/cffi0/backend_tests.py @@ -1,4 +1,5 @@ import py +import pytest import platform import sys, ctypes from cffi import FFI, CDefError, FFIError, VerificationMissing @@ -112,10 +113,14 @@ class BackendTests: p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): ffi = FFI(backend=self.Backend()) @@ -140,18 +145,21 @@ class BackendTests: ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "<cdata 'int[]' owning %d bytes>" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "<cdata 'int[]' owning 0 bytes>" @@ -259,7 +267,8 @@ class BackendTests: p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): ffi = FFI(backend=self.Backend()) @@ -386,7 +395,8 @@ class BackendTests: n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -422,13 +432,15 @@ class BackendTests: assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct foo*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "<cdata 'struct foo *' owning %d bytes>" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -450,8 +462,10 @@ class BackendTests: assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): ffi = FFI(backend=self.Backend()) @@ -511,11 +525,13 @@ class BackendTests: u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union foo*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "<cdata 'union foo *' owning %d bytes>" % SIZE_OF_INT def test_union_opaque(self): @@ -591,7 +607,8 @@ class BackendTests: p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -615,7 +632,8 @@ class BackendTests: p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -633,7 +651,8 @@ class BackendTests: s = ffi.new("struct foo*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -657,18 +676,21 @@ class BackendTests: a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) @@ -687,7 +709,8 @@ class BackendTests: q = ffi.new("int(**)(int)", p) assert repr(q) == "<cdata 'int(* *)(int)' owning %d bytes>" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -912,10 +935,14 @@ class BackendTests: assert s.e == 4294967295 assert s[0].e == 4294967295 s.e = s.e - py.test.raises(TypeError, "s.e = 'B'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) @@ -950,11 +977,14 @@ class BackendTests: ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): ffi = FFI(backend=self.Backend()) @@ -1011,17 +1041,23 @@ class BackendTests: assert ffi.sizeof("struct foo") == 8 s = ffi.new("struct foo *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1279,7 +1315,8 @@ class BackendTests: p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): ffi = FFI(backend=self.Backend()) diff --git a/testing/cffi0/test_ffi_backend.py b/testing/cffi0/test_ffi_backend.py index 12ecaee..6937a79 100644 --- a/testing/cffi0/test_ffi_backend.py +++ b/testing/cffi0/test_ffi_backend.py @@ -129,6 +129,36 @@ class TestFFI(backend_tests.BackendTests, alloc5 = ffi.new_allocator(myalloc5) py.test.raises(MemoryError, alloc5, "int[5]") + def test_new_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { int len[100]; short data[]; }; + struct bar_s { int abc[100]; struct foo_s tail; }; + """) + # loop to try to detect heap overwrites, if the size allocated + # is too small + for i in range(1, 501, 100): + p = ffi.new("struct bar_s *", [[10], [[20], [3,4,5,6,7,8,9] * i]]) + assert p.abc[0] == 10 + assert p.tail.len[0] == 20 + assert p.tail.data[0] == 3 + assert p.tail.data[6] == 9 + assert p.tail.data[7 * i - 1] == 9 + + def test_bogus_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { signed char len; signed char data[]; }; + struct bar_s { struct foo_s foo; int bcd; }; + """) + p = ffi.new("struct bar_s *", [[123, [45, 56, 67, 78]], 9999999]) + assert p.foo.len == 123 + assert p.foo.data[0] == 45 + assert p.foo.data[1] == 56 + assert p.foo.data[2] == 67 + assert p.bcd == 9999999 + assert p.foo.data[3] != 78 # has been overwritten with 9999999 + class TestBitfield: def check(self, source, expected_ofs_y, expected_align, expected_size): @@ -268,12 +298,15 @@ class TestBitfield: def test_error_cases(self): ffi = FFI() - py.test.raises(TypeError, - 'ffi.cdef("struct s1 { float x:1; };"); ffi.new("struct s1 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s2 { char x:0; };"); ffi.new("struct s2 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s3 { char x:9; };"); ffi.new("struct s3 *")') + ffi.cdef("struct s1 { float x:1; };") + with pytest.raises(TypeError): + ffi.new("struct s1 *") + ffi.cdef("struct s2 { char x:0; };") + with pytest.raises(TypeError): + ffi.new("struct s2 *") + ffi.cdef("struct s3 { char x:9; };") + with pytest.raises(TypeError): + ffi.new("struct s3 *") def test_struct_with_typedef(self): ffi = FFI() diff --git a/testing/cffi0/test_function.py b/testing/cffi0/test_function.py index ca2353f..120d7eb 100644 --- a/testing/cffi0/test_function.py +++ b/testing/cffi0/test_function.py @@ -1,4 +1,5 @@ import py +import pytest from cffi import FFI, CDefError import math, os, sys import ctypes.util @@ -90,7 +91,8 @@ class TestFunction(object): """) m = ffi.dlopen(lib_m) assert m.FOOBAR == 42 - py.test.raises(NotImplementedError, "m.baz") + with pytest.raises(NotImplementedError): + m.baz def test_tlsalloc(self): if sys.platform != 'win32': diff --git a/testing/cffi0/test_ownlib.py b/testing/cffi0/test_ownlib.py index f4f9ee2..a06df20 100644 --- a/testing/cffi0/test_ownlib.py +++ b/testing/cffi0/test_ownlib.py @@ -351,6 +351,8 @@ class TestOwnLib(object): def test_modify_struct_value(self): if self.module is None: py.test.skip("fix the auto-generation of the tiny test lib") + if self.Backend is CTypesBackend: + py.test.skip("fails with the ctypes backend on some architectures") ffi = FFI(backend=self.Backend()) ffi.cdef(""" typedef struct { diff --git a/testing/cffi0/test_parsing.py b/testing/cffi0/test_parsing.py index fb25ea0..2c29b86 100644 --- a/testing/cffi0/test_parsing.py +++ b/testing/cffi0/test_parsing.py @@ -481,3 +481,39 @@ def test_error_invalid_syntax_for_cdef(): assert str(e.value) == ('<cdef source string>:1: unexpected <FuncDef>: ' 'this construct is valid C but not valid in cdef()') +def test_unsigned_int_suffix_for_constant(): + ffi = FFI() + ffi.cdef("""enum e { + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py index 79e1c6c..dd643a5 100644 --- a/testing/cffi0/test_verify.py +++ b/testing/cffi0/test_verify.py @@ -1,4 +1,5 @@ import py, re +import pytest import sys, os, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model, FFIError from testing.support import * @@ -20,7 +21,8 @@ else: extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): def verify(self, *args, **kwds): @@ -589,7 +591,8 @@ def test_struct_array_guess_length(): assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -647,7 +650,8 @@ def test_struct_with_bitfield_exact(): ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1463,8 +1467,10 @@ def test_bool(): p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1532,7 +1538,8 @@ def test_cannot_pass_float(): } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2098,6 +2105,11 @@ def _run_in_multiple_threads(test1): raise errors[0][1] def test_errno_working_even_with_pypys_jit(): + # NOTE: on some platforms, to work correctly, this test needs to be + # compiled with -pthread. Otherwise, the accesses to errno done from f() + # are compiled by assuming this small library won't be used from multiple + # threads, which is wrong. If you see failures _and_ if you pass your + # own CFLAGS environment variable, please make sure "-pthread" is in it. ffi = FFI() ffi.cdef("int f(int);") lib = ffi.verify(""" diff --git a/testing/cffi0/test_zintegration.py b/testing/cffi0/test_zintegration.py index d56dac2..4cce595 100644 --- a/testing/cffi0/test_zintegration.py +++ b/testing/cffi0/test_zintegration.py @@ -1,11 +1,13 @@ import py, os, sys, shutil import subprocess from testing.udir import udir +import pytest if sys.platform == 'win32': - py.test.skip('snippets do not run on win32') + pytestmark = pytest.mark.skip('snippets do not run on win32') if sys.version_info < (2, 7): - py.test.skip('fails e.g. on a Debian/Ubuntu which patches virtualenv' + pytestmark = pytest.mark.skip( + 'fails e.g. on a Debian/Ubuntu which patches virtualenv' ' in a non-2.6-friendly way') def create_venv(name): |