Revision: 19266 http://gar.svn.sourceforge.net/gar/?rev=19266&view=rev Author: chninkel Date: 2012-09-22 13:05:00 +0000 (Sat, 22 Sep 2012) Log Message: ----------- added unit test + some fixes
Modified Paths: -------------- csw/mgar/gar/v2-yann/lib/python/common_constants.py csw/mgar/gar/v2-yann/lib/python/inspective_package.py csw/mgar/gar/v2-yann/lib/python/inspective_package_test.py Modified: csw/mgar/gar/v2-yann/lib/python/common_constants.py =================================================================== --- csw/mgar/gar/v2-yann/lib/python/common_constants.py 2012-09-22 09:38:33 UTC (rev 19265) +++ csw/mgar/gar/v2-yann/lib/python/common_constants.py 2012-09-22 13:05:00 UTC (rev 19266) @@ -34,6 +34,7 @@ DEFAULT_INSTALL_CONTENTS_FILE = "/var/sadm/install/contents" DUMP_BIN = "/usr/ccs/bin/dump" +ELFDUMP_BIN = "/usr/ccs/bin/elfdump" OWN_PKGNAME_PREFIXES = frozenset(["CSW"]) Modified: csw/mgar/gar/v2-yann/lib/python/inspective_package.py =================================================================== --- csw/mgar/gar/v2-yann/lib/python/inspective_package.py 2012-09-22 09:38:33 UTC (rev 19265) +++ csw/mgar/gar/v2-yann/lib/python/inspective_package.py 2012-09-22 13:05:00 UTC (rev 19266) @@ -254,7 +254,8 @@ for binary in binaries: binary_abspath = os.path.join(self.directory, "root", binary) # elfdump is the only tool that give us all informations - retcode, stdout, stderr = ShellCommand(["/usr/ccs/bin/elfdump", "-svy", binary_abspath]) + args = [common_constants.ELFDUMP_BIN, "-svy", binary_abspath] + retcode, stdout, stderr = ShellCommand(args) if retcode or stderr: logging.error("%s returned one or more errors: %s", args, stderr) continue @@ -268,7 +269,7 @@ # the key is the original field name and the value the destination field name elf_fields = {'version definition': { 'version': 'version', - 'dependency': 'dependancy', + 'dependency': 'dependency', }, 'version needed': { 'file': 'soname', @@ -277,6 +278,7 @@ 'symbol table': { 'name': 'symbol', 'ver': 'version', + 'type': 'type', 'bind': 'bind', 'shndx': 'shndx', }, @@ -320,6 +322,7 @@ binary_info['version definition'].pop(0) binary_info['symbol table'] = symbols.values() + binary_info['symbol table'].sort(key=lambda m: m['symbol']) # To not rely of the section order output of elfdump, we resolve symbol version # informations here after having parsed all elfdump output self._ResolveSymbolsVersionInfo (binary_info) @@ -337,7 +340,8 @@ # this could be potentially moved into the DirectoryFormatPackage class. # ldd needs the binary to be executable os.chmod(binary_abspath, 0755) - retcode, stdout, stderr = ShellCommand(["ldd", "-Ur", binary_abspath]) + args = ["ldd", "-Ur", binary_abspath] + retcode, stdout, stderr = ShellCommand(args) if retcode: uname_info = os.uname() if (uname_info[2] == '5.9' and uname_info[4] == 'i86pc' and @@ -373,17 +377,21 @@ version_info = binary_info['version definition'] + binary_info['version needed'] for sym_info in binary_info['symbol table']: - # version index is an 1-based index on the version information table - # from which we also removed the first entry which was the - # base library/binary itself + # sym_info version field is an 1-based index on the version information table + # we don't care about 0 and 1 values: + # 0 is for external symbol with no version information available + # 1 is for a symbol defined by the binary and not binded to a version interface + # but we removed that (useless) entry from the version definition table version_index = int(sym_info['version']) - 2 if version_index >= 0: version = version_info[version_index] sym_info['version'] = version['version'] - sym_info['soname'] = version['soname'] + if 'soname' in version: + sym_info['soname'] = version['soname'] + else: + sym_info['version'] = None # we make sure these fields are present even if the syminfo section is not - sym_info.setdefault('version') sym_info.setdefault('soname') sym_info.setdefault('flags') @@ -410,8 +418,9 @@ 'version definition': (r""" \s*(?:\[(?P<index>\d+)\]\s+)? # index might be not present # if no version binding is enabled - (?P<version>.*\S) - \s+(?P<dependency>\S+)?\s*$ + (?P<version>\S+) + (?:\s+(?P<dependency>\S+))? + (?:\s+\[\s(?:BASE)\s\])?\s*$ # """), 'version needed': (r""" \s*(?:\[(?P<index>\d+)\]\s+)? # index might be not present @@ -428,21 +437,21 @@ \s*\[\d+\] \s+(?:0x[0-9a-f]+|REG_G\d+) \s+0x[0-9a-f]+ - \s+\S+ + \s+(?P<type>\S+) \s+(?P<bind>\S+) \s+\S+ \s+(?P<ver>\S+) \s+(?P<shndx>\S+) - \s+(?P<name>\S+)?\s*$ + (?:\s+(?P<name>\S+))?\s*$ """), 'syminfo': (r""" \s*\[\d+\] \s+(?P<flags>[ABCDFILNPS]+) \s+(?:(?:\[\d+\] # some kind of library index - \s+(?P<library>.*\S)|<self>)\s+)? # library is not present + \s+(?P<library>\S+)|<self>)\s+)? # library is not present # for external symbols not # directly bound - (?P<symbol>.*\S)\s* + (?P<symbol>\S+)\s* """)} elfdump_data = None Modified: csw/mgar/gar/v2-yann/lib/python/inspective_package_test.py =================================================================== --- csw/mgar/gar/v2-yann/lib/python/inspective_package_test.py 2012-09-22 09:38:33 UTC (rev 19265) +++ csw/mgar/gar/v2-yann/lib/python/inspective_package_test.py 2012-09-22 13:05:00 UTC (rev 19266) @@ -6,6 +6,7 @@ import hachoir_parser import magic import os +import common_constants LDD_R_OUTPUT_1 = """\tlibc.so.1 => /lib/libc.so.1 \tsymbol not found: check_encoding_conversion_args (/opt/csw/lib/postgresql/8.4/utf8_and_gbk.so) @@ -69,6 +70,89 @@ self.assertEqual([u'/fake/path/CSWfoo/root/foo-file'], ip.ListBinaries()) + + + def testGetBinaryElfInfo(self): + + fake_binary = 'opt/csw/lib/libssl.so.1.0.0' + fake_package_path = '/fake/path/CSWfoo' + fake_elfdump_output = ''' +Version Definition Section: .SUNW_version + index version dependency + [1] libssl.so.1.0.0 [ BASE ] + [2] OPENSSL_1.0.0 + [3] OPENSSL_1.0.1 OPENSSL_1.0.0 + +Version Needed Section: .SUNW_version + index file version + [4] libcrypto.so.1.0.0 OPENSSL_1.0.0 [ INFO ] + [5] OPENSSL_1.0.1 + [6] libnsl.so.1 SUNW_1.9.1 + +Symbol Table Section: .dynsym + index value size type bind oth ver shndx name + [0] 0x00000000 0x00000000 NOTY LOCL D 0 UNDEF + [1] 0x00000000 0x00000000 FUNC GLOB D 4 UNDEF EVP_DigestSignFinal + [2] 0x0003ead4 0x000000dc FUNC GLOB P 2 .text SSL_get_shared_ciphers + [3] 0x0004f8f8 0x00000014 FUNC GLOB P 3 .text SSL_CTX_set_srp_client_pwd_callback + [4] 0x00000000 0x00000000 FUNC GLOB D 5 UNDEF SRP_Calc_client_key + [5] 0x000661a0 0x00000000 OBJT GLOB P 1 .got _GLOBAL_OFFSET_TABLE_ + +Syminfo Section: .SUNW_syminfo + index flags bound to symbol + [1] DBL [1] libcrypto.so.1.0.0 EVP_DigestSignFinal + [2] DB <self> SSL_get_shared_ciphers + [3] DB <self> SSL_CTX_set_srp_client_pwd_callback + [4] DBL [1] libcrypto.so.1.0.0 SRP_Calc_client_key + [5] DB <self> _GLOBAL_OFFSET_TABLE_ +''' + fake_binary_elfinfo = {'opt/csw/lib/libssl.so.1.0.0': { + 'symbol table': [ + {'shndx': 'UNDEF', 'soname': None, 'bind': 'LOCL', + 'symbol': None, 'version': None, 'flags': None, 'type': 'NOTY'}, + {'shndx': 'UNDEF', 'soname': 'libcrypto.so.1.0.0', 'bind': 'GLOB', + 'symbol': 'EVP_DigestSignFinal', 'version': 'OPENSSL_1.0.0', + 'flags': 'DBL', 'type': 'FUNC'}, + {'shndx': 'UNDEF', 'soname': 'libcrypto.so.1.0.0', 'bind': 'GLOB', + 'symbol': 'SRP_Calc_client_key', 'version': 'OPENSSL_1.0.1', + 'flags': 'DBL', 'type': 'FUNC'}, + {'shndx': '.text', 'soname': None, 'bind': 'GLOB', + 'symbol': 'SSL_CTX_set_srp_client_pwd_callback', + 'version': 'OPENSSL_1.0.1', 'flags': 'DB', 'type': 'FUNC'}, + {'shndx': '.text', 'soname': None, 'bind': 'GLOB', + 'symbol': 'SSL_get_shared_ciphers', 'version': 'OPENSSL_1.0.0', + 'flags': 'DB', 'type': 'FUNC'}, + {'shndx': '.got', 'soname': None, 'bind': 'GLOB', + 'symbol': '_GLOBAL_OFFSET_TABLE_', 'version': None, + 'flags': 'DB', 'type': 'OBJT'}, + ], + 'version definition': [ + {'dependency': None, 'version': 'OPENSSL_1.0.0'}, + {'dependency': 'OPENSSL_1.0.0', 'version': 'OPENSSL_1.0.1'}, + ], + 'version needed': [ + {'version': 'OPENSSL_1.0.0', 'soname': 'libcrypto.so.1.0.0'}, + {'version': 'OPENSSL_1.0.1', 'soname': 'libcrypto.so.1.0.0'}, + {'version': 'SUNW_1.9.1', 'soname': 'libnsl.so.1'}, + ] + } + } + + ip = inspective_package.InspectivePackage(fake_package_path) + self.mox.StubOutWithMock(ip, 'ListBinaries') + ip.ListBinaries().AndReturn([fake_binary]) + + self.mox.StubOutWithMock(inspective_package, 'ShellCommand') + args = [common_constants.ELFDUMP_BIN, + '-svy', + os.path.join(fake_package_path, "root", fake_binary)] + inspective_package.ShellCommand(args).AndReturn((0, fake_elfdump_output, "")) + self.mox.ReplayAll() + + self.assertEqual(fake_binary_elfinfo, ip.GetBinaryElfInfo()) + + + class PackageStatsUnitTest(unittest.TestCase): def setUp(self): @@ -80,7 +164,7 @@ def test_ParseElfdumpLineVersionNeeded(self): line = '[13] SUNW_0.9 [ INFO ]' - expected = { + expected = { 'index': '13', 'version': 'SUNW_0.9', 'file': None @@ -89,11 +173,12 @@ def test_ParseElfdumpLineSymbolTable(self): line = ' [9] 0x000224b8 0x0000001c FUNC GLOB D 1 .text vsf_log_line' - expected = { - 'bind': 'GLOB', - 'shndx': '.text', - 'name': 'vsf_log_line', - 'ver': '1' + expected = { + 'bind': 'GLOB', + 'shndx': '.text', + 'name': 'vsf_log_line', + 'ver': '1', + 'type': 'FUNC', } self.assertEqual((expected, 'symbol table'), self.ip._ParseElfdumpLine(line, 'symbol table')) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ devel mailing list devel@lists.opencsw.org https://lists.opencsw.org/mailman/listinfo/devel