Home | History | Annotate | Download | only in test
      1 from ctypes import *
      2 import os
      3 import sys
      4 import unittest
      5 import test.support
      6 from ctypes.util import find_library
      7 
      8 libc_name = None
      9 
     10 def setUpModule():
     11     global libc_name
     12     if os.name == "nt":
     13         libc_name = find_library("c")
     14     elif sys.platform == "cygwin":
     15         libc_name = "cygwin1.dll"
     16     else:
     17         libc_name = find_library("c")
     18 
     19     if test.support.verbose:
     20         print("libc_name is", libc_name)
     21 
     22 class LoaderTest(unittest.TestCase):
     23 
     24     unknowndll = "xxrandomnamexx"
     25 
     26     def test_load(self):
     27         if libc_name is None:
     28             self.skipTest('could not find libc')
     29         CDLL(libc_name)
     30         CDLL(os.path.basename(libc_name))
     31         self.assertRaises(OSError, CDLL, self.unknowndll)
     32 
     33     def test_load_version(self):
     34         if libc_name is None:
     35             self.skipTest('could not find libc')
     36         if os.path.basename(libc_name) != 'libc.so.6':
     37             self.skipTest('wrong libc path for test')
     38         cdll.LoadLibrary("libc.so.6")
     39         # linux uses version, libc 9 should not exist
     40         self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9")
     41         self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll)
     42 
     43     def test_find(self):
     44         for name in ("c", "m"):
     45             lib = find_library(name)
     46             if lib:
     47                 cdll.LoadLibrary(lib)
     48                 CDLL(lib)
     49 
     50     @unittest.skipUnless(os.name == "nt",
     51                          'test specific to Windows')
     52     def test_load_library(self):
     53         # CRT is no longer directly loadable. See issue23606 for the
     54         # discussion about alternative approaches.
     55         #self.assertIsNotNone(libc_name)
     56         if test.support.verbose:
     57             print(find_library("kernel32"))
     58             print(find_library("user32"))
     59 
     60         if os.name == "nt":
     61             windll.kernel32.GetModuleHandleW
     62             windll["kernel32"].GetModuleHandleW
     63             windll.LoadLibrary("kernel32").GetModuleHandleW
     64             WinDLL("kernel32").GetModuleHandleW
     65             # embedded null character
     66             self.assertRaises(ValueError, windll.LoadLibrary, "kernel32\0")
     67 
     68     @unittest.skipUnless(os.name == "nt",
     69                          'test specific to Windows')
     70     def test_load_ordinal_functions(self):
     71         import _ctypes_test
     72         dll = WinDLL(_ctypes_test.__file__)
     73         # We load the same function both via ordinal and name
     74         func_ord = dll[2]
     75         func_name = dll.GetString
     76         # addressof gets the address where the function pointer is stored
     77         a_ord = addressof(func_ord)
     78         a_name = addressof(func_name)
     79         f_ord_addr = c_void_p.from_address(a_ord).value
     80         f_name_addr = c_void_p.from_address(a_name).value
     81         self.assertEqual(hex(f_ord_addr), hex(f_name_addr))
     82 
     83         self.assertRaises(AttributeError, dll.__getitem__, 1234)
     84 
     85     @unittest.skipUnless(os.name == "nt", 'Windows-specific test')
     86     def test_1703286_A(self):
     87         from _ctypes import LoadLibrary, FreeLibrary
     88         # On winXP 64-bit, advapi32 loads at an address that does
     89         # NOT fit into a 32-bit integer.  FreeLibrary must be able
     90         # to accept this address.
     91 
     92         # These are tests for http://www.python.org/sf/1703286
     93         handle = LoadLibrary("advapi32")
     94         FreeLibrary(handle)
     95 
     96     @unittest.skipUnless(os.name == "nt", 'Windows-specific test')
     97     def test_1703286_B(self):
     98         # Since on winXP 64-bit advapi32 loads like described
     99         # above, the (arbitrarily selected) CloseEventLog function
    100         # also has a high address.  'call_function' should accept
    101         # addresses so large.
    102         from _ctypes import call_function
    103         advapi32 = windll.advapi32
    104         # Calling CloseEventLog with a NULL argument should fail,
    105         # but the call should not segfault or so.
    106         self.assertEqual(0, advapi32.CloseEventLog(None))
    107         windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p
    108         windll.kernel32.GetProcAddress.restype = c_void_p
    109         proc = windll.kernel32.GetProcAddress(advapi32._handle,
    110                                               b"CloseEventLog")
    111         self.assertTrue(proc)
    112         # This is the real test: call the function via 'call_function'
    113         self.assertEqual(0, call_function(proc, (None,)))
    114 
    115 if __name__ == "__main__":
    116     unittest.main()
    117