From 94f3b6906e7c64696bad411c94b60f0289e92625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Nowak?= <luke@nexedi.com> Date: Mon, 22 Nov 2010 09:27:52 +0000 Subject: [PATCH] - add a tests which asserts that all dynamically linkable files are correctly linked (or inside of builout or with glibc) git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@40443 20353a03-c40f-0410-a6d1-a30d3c3de9de --- buildout/tests/assertSoftware.py | 78 ++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/buildout/tests/assertSoftware.py b/buildout/tests/assertSoftware.py index 072302d8da..9276494e52 100644 --- a/buildout/tests/assertSoftware.py +++ b/buildout/tests/assertSoftware.py @@ -30,6 +30,30 @@ import os import subprocess import unittest +# List of libraries which are acceptable to be linked in globally +ACCEPTABLE_GLOBAL_LIB_LIST = ( + # 32 bit Linux + '/lib/ld-linux.so', + '/lib/libc.so', + '/lib/libcrypt.so', + '/lib/libdl.so', + '/lib/libm.so', + '/lib/libnsl.so', + '/lib/libpthread.so', + '/lib/libutil.so', + # 64 bit Linux + '/lib64/ld-linux-x86-64.so', + '/lib64/libc.so', + '/lib64/libcrypt.so', + '/lib64/libdl.so', + '/lib64/libm.so', + '/lib64/libnsl.so', + '/lib64/libpthread.so', + '/lib64/libutil.so', + # Arch independed Linux + 'linux-vdso.so', +) + def getCleanList(s): """Converts free form string separated by whitespaces to python list""" return sorted([q.strip() for q in s.split() if len(q.strip()) > 0]) @@ -60,6 +84,31 @@ def readElfAsDict(f): runpath_list=sorted(runpath_list) ) +def readLddInfoList(f): + popen = subprocess.Popen(['ldd', f], stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + link_list = [] + a = link_list.append + result = popen.communicate()[0] + if 'not a dynamic executable' in result: + return link_list + for line in result.split('\n'): + line = line.strip() + if '=>' in line: + lib, path = line.split('=>') + lib = lib.strip() + path = path.strip() + if lib in path: + # libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f77fcebf000) + a(path.split()[0]) + else: + # linux-vdso.so.1 => (0x00007fffa7fff000) + a(lib) + elif line: + # /lib64/ld-linux-x86-64.so.2 (0x00007f77fd400000) + a(line.split()[0]) + return link_list + class AssertSoftwareMixin(unittest.TestCase): def assertEqual(self, first, second, msg=None): try: @@ -83,6 +132,20 @@ class AssertSoftwareMixin(unittest.TestCase): else: raise + def assertSoftwareDictEmpty(self, first, msg=None): + try: + return unittest.TestCase.assertEqual(self, first, {}, msg) + except unittest.TestCase.failureException: + if msg is None: + msg = '' + for path, wrong_link_list in first.iteritems(): + msg += '%s:\n' % path + msg += '\n'.join(['\t' + q for q in sorted(wrong_link_list)]) + '\n' + msg = 'Bad linked software:\n%s' % msg + raise unittest.TestCase.failureException, msg + else: + raise + class AssertSoftwareRunable(AssertSoftwareMixin): def test_HaProxy(self): stdout, stderr = subprocess.Popen(["parts/haproxy/sbin/haproxy", "-v"], @@ -1069,5 +1132,20 @@ class AssertItools(AssertSoftwareMixin): software in ['glib']] self.assertEqual(sorted(expected_rpath_list), elf_dict['runpath_list']) +class AssertElfLinkedInternally(AssertSoftwareMixin): + def test(self): + result_dict = {} + root = os.path.join(os.path.abspath(os.curdir), 'parts') + for dirpath, dirlist, filelist in os.walk(root): + for filename in filelist: + filename = os.path.join(dirpath, filename) + link_list = readLddInfoList(filename) + bad_link_list = [q for q in link_list if not q.startswith(root) \ + and not any([q.startswith(k) for k in ACCEPTABLE_GLOBAL_LIB_LIST])] + if len(bad_link_list): + result_dict[filename] = bad_link_list + self.assertSoftwareDictEmpty(result_dict) + + if __name__ == '__main__': unittest.main() -- 2.30.9