import unittest import os.path import sys import test.support from ctypes import * from ctypes.util import find_library # On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode. class Test_OpenGL_libs(unittest.TestCase): @classmethod def setUpClass(cls): lib_gl = lib_glu = lib_gle = None if sys.platform == "win32": lib_gl = find_library("OpenGL32") lib_glu = find_library("Glu32") elif sys.platform == "darwin": lib_gl = lib_glu = find_library("OpenGL") else: lib_gl = find_library("GL") lib_glu = find_library("GLU") lib_gle = find_library("gle") ## print, for debugging if test.support.verbose: print("OpenGL libraries:") for item in (("GL", lib_gl), ("GLU", lib_glu), ("gle", lib_gle)): print("\t", item) cls.gl = cls.glu = cls.gle = None if lib_gl: try: cls.gl = CDLL(lib_gl, mode=RTLD_GLOBAL) except OSError: pass if lib_glu: try: cls.glu = CDLL(lib_glu, RTLD_GLOBAL) except OSError: pass if lib_gle: try: cls.gle = CDLL(lib_gle) except OSError: pass @classmethod def tearDownClass(cls): cls.gl = cls.glu = cls.gle = None def test_gl(self): if self.gl is None: self.skipTest('lib_gl not available') self.gl.glClearIndex def test_glu(self): if self.glu is None: self.skipTest('lib_glu not available') self.glu.gluBeginCurve def test_gle(self): if self.gle is None: self.skipTest('lib_gle not available') self.gle.gleGetJoinStyle def test_shell_injection(self): result = find_library('; echo Hello shell > ' + test.support.TESTFN) self.assertFalse(os.path.lexists(test.support.TESTFN)) self.assertIsNone(result) @unittest.skipUnless(sys.platform.startswith('linux'), 'Test only valid for Linux') class LibPathFindTest(unittest.TestCase): def test_find_on_libpath(self): import subprocess import tempfile try: p = subprocess.Popen(['gcc', '--version'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) out, _ = p.communicate() except OSError: raise unittest.SkipTest('gcc, needed for test, not available') with tempfile.TemporaryDirectory() as d: # create an empty temporary file srcname = os.path.join(d, 'dummy.c') libname = 'py_ctypes_test_dummy' dstname = os.path.join(d, 'lib%s.so' % libname) with open(srcname, 'w') as f: pass self.assertTrue(os.path.exists(srcname)) # compile the file to a shared library cmd = ['gcc', '-o', dstname, '--shared', '-Wl,-soname,lib%s.so' % libname, srcname] out = subprocess.check_output(cmd) self.assertTrue(os.path.exists(dstname)) # now check that the .so can't be found (since not in # LD_LIBRARY_PATH) self.assertIsNone(find_library(libname)) # now add the location to LD_LIBRARY_PATH with test.support.EnvironmentVarGuard() as env: KEY = 'LD_LIBRARY_PATH' if KEY not in env: v = d else: v = '%s:%s' % (env[KEY], d) env.set(KEY, v) # now check that the .so can be found (since in # LD_LIBRARY_PATH) self.assertEqual(find_library(libname), 'lib%s.so' % libname) if __name__ == "__main__": unittest.main()