summaryrefslogtreecommitdiff
path: root/testing/test_ownlib.py
blob: 22c580668f6a3be2f39c9a263e7ac5181ade0a02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import py, sys
import subprocess, weakref
from cffi import FFI
from cffi.backend_ctypes import CTypesBackend


SOURCE = """\
#include <errno.h>

int test_getting_errno(void) {
    errno = 123;
    return -1;
}

int test_setting_errno(void) {
    return errno;
}

int my_array[7] = {0, 1, 2, 3, 4, 5, 6};
"""

class TestOwnLib(object):
    Backend = CTypesBackend

    def setup_class(cls):
        if sys.platform == 'win32':
            return
        from testing.udir import udir
        udir.join('testownlib.c').write(SOURCE)
        subprocess.check_call(
            'gcc testownlib.c -shared -fPIC -o testownlib.so',
            cwd=str(udir), shell=True)
        cls.module = str(udir.join('testownlib.so'))

    def test_getting_errno(self):
        if sys.platform == 'win32':
            py.test.skip("fix the auto-generation of the tiny test lib")
        ffi = FFI(backend=self.Backend())
        ffi.cdef("""
            int test_getting_errno(void);
        """)
        ownlib = ffi.dlopen(self.module)
        res = ownlib.test_getting_errno()
        assert res == -1
        assert ffi.errno == 123

    def test_setting_errno(self):
        if sys.platform == 'win32':
            py.test.skip("fix the auto-generation of the tiny test lib")
        if self.Backend is CTypesBackend and '__pypy__' in sys.modules:
            py.test.skip("XXX errno issue with ctypes on pypy?")
        ffi = FFI(backend=self.Backend())
        ffi.cdef("""
            int test_setting_errno(void);
        """)
        ownlib = ffi.dlopen(self.module)
        ffi.errno = 42
        res = ownlib.test_setting_errno()
        assert res == 42
        assert ffi.errno == 42

    def test_my_array_7(self):
        if sys.platform == 'win32':
            py.test.skip("fix the auto-generation of the tiny test lib")
        ffi = FFI(backend=self.Backend())
        ffi.cdef("""
            int my_array[7];
        """)
        ownlib = ffi.dlopen(self.module)
        for i in range(7):
            assert ownlib.my_array[i] == i
        assert len(ownlib.my_array) == 7
        if self.Backend is CTypesBackend:
            py.test.skip("not supported by the ctypes backend")
        ownlib.my_array = list(range(10, 17))
        for i in range(7):
            assert ownlib.my_array[i] == 10 + i
        ownlib.my_array = list(range(7))
        for i in range(7):
            assert ownlib.my_array[i] == i

    def test_my_array_no_length(self):
        if sys.platform == 'win32':
            py.test.skip("fix the auto-generation of the tiny test lib")
        if self.Backend is CTypesBackend:
            py.test.skip("not supported by the ctypes backend")
        ffi = FFI(backend=self.Backend())
        ffi.cdef("""
            int my_array[];
        """)
        ownlib = ffi.dlopen(self.module)
        for i in range(7):
            assert ownlib.my_array[i] == i
        py.test.raises(TypeError, len, ownlib.my_array)
        ownlib.my_array = list(range(10, 17))
        for i in range(7):
            assert ownlib.my_array[i] == 10 + i
        ownlib.my_array = list(range(7))
        for i in range(7):
            assert ownlib.my_array[i] == i

    def test_keepalive_lib(self):
        if sys.platform == 'win32':
            py.test.skip("fix the auto-generation of the tiny test lib")
        ffi = FFI(backend=self.Backend())
        ffi.cdef("""
            int test_getting_errno(void);
        """)
        ownlib = ffi.dlopen(self.module)
        ffi_r = weakref.ref(ffi)
        ownlib_r = weakref.ref(ownlib)
        func = ownlib.test_getting_errno
        del ffi
        import gc; gc.collect()       # ownlib stays alive
        assert ownlib_r() is not None
        assert ffi_r() is not None    # kept alive by ownlib
        res = func()
        assert res == -1

    def test_keepalive_ffi(self):
        if sys.platform == 'win32':
            py.test.skip("fix the auto-generation of the tiny test lib")
        ffi = FFI(backend=self.Backend())
        ffi.cdef("""
            int test_getting_errno(void);
        """)
        ownlib = ffi.dlopen(self.module)
        ffi_r = weakref.ref(ffi)
        ownlib_r = weakref.ref(ownlib)
        func = ownlib.test_getting_errno
        del ownlib
        import gc; gc.collect()       # ffi stays alive
        assert ffi_r() is not None
        assert ownlib_r() is not None # kept alive by ffi
        res = func()
        assert res == -1
        assert ffi.errno == 123