Files
autospec/tests/test_abireport.py
Matthew Johnson 101b2f74bb Add unit tests for abireport
Tests most helper functions in the abireport module. Excludes some
helpers that are just wrappers for os and shutil calls. Also excludes
the 100-line examine_abi main method, which may require functional
tests.
2017-01-24 15:01:38 -08:00

274 lines
11 KiB
Python

import unittest
import abireport
def mock_return(retval):
"""
Simple mock method to set return value of a function
"""
def mock_fn(_):
return retval
return mock_fn
class TestAbireport(unittest.TestCase):
def test_get_soname(self):
"""
Test get_soname function with valid get_output results
"""
backup = abireport.get_output
abireport.get_output = mock_return('SONAME libtest.so.14')
self.assertEqual(abireport.get_soname('test'), 'libtest.so.14')
abireport.get_output = backup
def test_get_soname_none(self):
"""
Test get_soname function with no get_output results
"""
backup = abireport.get_output
abireport.get_output = mock_return('')
self.assertEqual(abireport.get_soname('test'), None)
abireport.get_output = backup
def test_get_soname_error(self):
"""
Test get_soname function with exception raised in get_output
"""
backup = abireport.get_output
def mock_get_output(cmd):
raise Exception('testing exception')
abireport.get_output = mock_get_output
self.assertEqual(abireport.get_soname('test'), None)
abireport.get_output = backup
def test_get_shared_dependencies(self):
"""
Test get_shared_dependencies function with valid get_output results
"""
backup = abireport.get_output
abireport.get_output = mock_return(READELF1)
results = set(['libdl.so.2', 'libz.so.1', 'libexpat.so.1',
'libstdc++.so.6', 'libm.so.6', 'libgcc_s.so.1',
'libc.so.6'])
self.assertEqual(abireport.get_shared_dependencies('test'), results)
abireport.get_output = backup
def test_get_shared_dependencies_none(self):
"""
Test get_shared_dependencies with no matches
"""
backup = abireport.get_output
abireport.get_output = mock_return(READELF2)
self.assertEqual(abireport.get_shared_dependencies('test'), set())
abireport.get_output = backup
def test_is_dynamic_binary(self):
"""
Test is_dynamic_binary function for True return
"""
backup_isfile = abireport.os.path.isfile
backup_exists = abireport.os.path.exists
backup_get_file_magic = abireport.get_file_magic
abireport.os.path.isfile = mock_return(True)
abireport.os.path.exists = mock_return(True)
abireport.get_file_magic = mock_return(FILEMAGIC1)
self.assertTrue(abireport.is_dynamic_binary('test'))
abireport.os.path.isfile = backup_isfile
abireport.os.path.exists = backup_exists
abireport.get_file_magic = backup_get_file_magic
def test_is_dynamic_binary_false(self):
"""
Test is_dynamic_binary function for False return
"""
backup_exists = abireport.os.path.exists
backup_isfile = abireport.os.path.isfile
backup_get_file_magic = abireport.get_file_magic
abireport.os.path.exists = mock_return(True)
abireport.os.path.isfile = mock_return(True)
abireport.get_file_magic = mock_return('This is not a matched string')
self.assertFalse(abireport.is_dynamic_binary('test'))
abireport.os.path.exists = backup_exists
abireport.os.path.isfile = backup_isfile
abireport.get_file_magic = backup_get_file_magic
def test_is_file_valid(self):
"""
Test is_file_valid function with valid file magic
"""
backup_exists = abireport.os.path.exists
backup_islink = abireport.os.path.islink
backup_get_file_magic = abireport.get_file_magic
abireport.os.path.exists = mock_return(True)
abireport.os.path.islink = mock_return(False)
abireport.get_file_magic = mock_return(FILEMAGIC1)
self.assertTrue(abireport.is_file_valid('test'))
abireport.os.path.exists = backup_exists
abireport.os.path.islink= backup_islink
abireport.get_file_magic = backup_get_file_magic
def test_is_file_valid_false(self):
"""
Test is_file_valid function with valid file magic
"""
backup_exists = abireport.os.path.exists
backup_islink = abireport.os.path.islink
backup_get_file_magic = abireport.get_file_magic
abireport.os.path.exists = mock_return(True)
abireport.os.path.islink = mock_return(False)
abireport.get_file_magic = mock_return('This is not a matched string')
self.assertFalse(abireport.is_file_valid('test'))
abireport.os.path.exists = backup_exists
abireport.os.path.islink= backup_islink
abireport.get_file_magic = backup_get_file_magic
def test_dump_symbols(self):
"""
Test dump_symbols function with valid nm output
"""
backup = abireport.get_output
abireport.get_output = mock_return(NM1)
results = set(['WXMPIterator_DecrementRefCount_1',
'WXMPIterator_IncrementRefCount_1',
'_Z13XMP_InitMutexP15pthread_mutex_t',
'_Z13XMP_TermMutexR15pthread_mutex_t',
'_Z14CloneOffspringPK8XMP_NodePS_',
'_Z14SortNamedNodesRSt6vectorIP8XMP_NodeSaIS1_EE',
'_Z15CompareSubtreesRK8XMP_NodeS1_',
'_ZN5Exiv211focalLengthERKNS_8ExifDataE',
'_ZN5Exiv211getRationalEPKhNS_9ByteOrderE',
'_ZN5Exiv211isBigEndianEv',
'_ZN5Exiv211orientationERKNS_8ExifDataE',
'_ZN5Exiv28GifImageC2ESt8auto_ptrINS_7BasicIoEE'])
self.assertEqual(abireport.dump_symbols('test'), results)
abireport.get_output = backup
def test_dump_symbols_exit(self):
"""
Test dump_symbols function with fatal exception
"""
backup = abireport.get_output
def mock_get_output(_):
raise Exception('This is a test exception')
abireport.get_output = mock_get_output
with self.assertRaises(SystemExit) as dumpsymbols:
abireport.dump_symbols('test')
self.assertEqual(dumpsymbols.exception.code, 1)
READELF1 = """
Dynamic section at offset 0x2d0788 contains 31 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libexpat.so.1]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libexiv2.so.14]
0x000000000000000f (RPATH) Library rpath: [/usr/lib]
0x000000000000000c (INIT) 0xca320
0x000000000000000d (FINI) 0x20e6cc
0x0000000000000019 (INIT_ARRAY) 0x2a5a70
0x000000000000001b (INIT_ARRAYSZ) 400 (bytes)
0x000000000000001a (FINI_ARRAY) 0x2a5c00
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x0000000000000004 (HASH) 0x1f0
0x0000000000000005 (STRTAB) 0x23f10
0x0000000000000006 (SYMTAB) 0x8ac0
0x000000000000000a (STRSZ) 252569 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0x2d19b8
0x0000000000000007 (RELA) 0x63f48
0x0000000000000008 (RELASZ) 418776 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x0000000000000018 (BIND_NOW)
0x000000006ffffffb (FLAGS_1) Flags: NOW
0x000000006ffffffe (VERNEED) 0x63e08
0x000000006fffffff (VERNEEDNUM) 5
0x000000006ffffff0 (VERSYM) 0x619aa
0x000000006ffffff9 (RELACOUNT) 11626
0x0000000000000000 (NULL) 0x0
"""
READELF2 = """
Dynamic section at offset 0x2d0788 contains 31 entries:
Tag Type Name/Value
0x000000000000000e (SONAME) Library soname: [libexiv2.so.14]
0x000000000000000f (RPATH) Library rpath: [/usr/lib]
0x000000000000000c (INIT) 0xca320
0x000000000000000d (FINI) 0x20e6cc
0x0000000000000019 (INIT_ARRAY) 0x2a5a70
0x000000000000001b (INIT_ARRAYSZ) 400 (bytes)
0x000000000000001a (FINI_ARRAY) 0x2a5c00
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x0000000000000004 (HASH) 0x1f0
0x0000000000000005 (STRTAB) 0x23f10
0x0000000000000006 (SYMTAB) 0x8ac0
0x000000000000000a (STRSZ) 252569 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0x2d19b8
0x0000000000000007 (RELA) 0x63f48
0x0000000000000008 (RELASZ) 418776 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x0000000000000018 (BIND_NOW)
0x000000006ffffffb (FLAGS_1) Flags: NOW
0x000000006ffffffe (VERNEED) 0x63e08
0x000000006fffffff (VERNEEDNUM) 5
0x000000006ffffff0 (VERSYM) 0x619aa
0x000000006ffffff9 (RELACOUNT) 11626
0x0000000000000000 (NULL) 0x0
"""
FILEMAGIC1 = '/path/to/so/libtest.so.1: ELF 64-bit LSB shared object, ' \
'x86-64, version 1 (SYSV), dynamically linked, ' \
'BuildID[sha1]=c99853fe0c5d8f3c7550848edf25fe7782fb22c3, stripped'
NM1 = """
00000000002f1d88 B voidStringPtr
00000000002f1d90 B voidVoidPtr
00000000002f1ce0 B void_wResult
00000000001d1a40 T WXMPIterator_DecrementRefCount_1
00000000001d19f0 T WXMPIterator_IncrementRefCount_1
00000000001daa80 T _Z13XMP_InitMutexP15pthread_mutex_t
00000000001daaa0 T _Z13XMP_TermMutexR15pthread_mutex_t
00000000001db900 T _Z14CloneOffspringPK8XMP_NodePS_
00000000001df4e0 A _Z14SortNamedNodesRSt6vectorIP8XMP_NodeSaIS1_EE
00000000001dc450 T _Z15CompareSubtreesRK8XMP_NodeS1_
000000000011d260 A _ZN5Exiv211focalLengthERKNS_8ExifDataE
00000000001b0510 T _ZN5Exiv211getRationalEPKhNS_9ByteOrderE
0000000000197160 T _ZN5Exiv211isBigEndianEv
000000000011c8e0 T _ZN5Exiv211orientationERKNS_8ExifDataE
00000000002c7000 D _ZN5Exiv211sectionInfoE
00000000002c45e0 D _ZN5Exiv212xmpXmpBJInfoE
0000000000137660 T _ZN5Exiv28GifImageC2ESt8auto_ptrINS_7BasicIoEE
00000000002658d8 R _ZN5Exiv28Internal10canonCfCfgE
0000000000265960 R _ZN5Exiv28Internal10canonCsCfgE
00000000002ebac0 B _ZN5Exiv28Internal14SigmaMakerNote8tagInfo_E
"""
if __name__ == '__main__':
unittest.main(buffer=True)