Skip to content

Commit

Permalink
Dependency tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
vadimcn committed Oct 12, 2020
1 parent 6003c77 commit 0abc418
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 30 deletions.
7 changes: 4 additions & 3 deletions CMakeLists.txt
Expand Up @@ -23,8 +23,9 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(NPM npm)
set(PathSep ":")
set(DefaultTarget x86_64-unknown-linux-gnu)
set(AllowedDependencies linux-vdso.so.1 librt.so.1 libdl.so.2 libpthread.so.0 libgcc_s.so.1
libm.so.6 libc.so.6 /lib64/ld-linux-x86-64.so.2)
set(AllowedDependencies liblldb.so libpython3.* linux-vdso.so.1 librt.so.1 libdl.so.2 libpthread.so.0 libgcc_s.so.1
libm.so.6 libc.so.6 libexpat.so.1 libz.so.1 libutil.so.1
/lib64/ld-linux-x86-64.so.2)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
set(DylibPrefix lib)
set(DylibSuffix .dylib)
Expand Down Expand Up @@ -285,7 +286,7 @@ endforeach(TestTriple)

add_custom_target(check
DEPENDS tests cargo_test
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
COMMAND ${CMAKE_CTEST_COMMAND} --verbose
)

# Install
Expand Down
7 changes: 3 additions & 4 deletions adapter/CMakeLists.txt
Expand Up @@ -63,7 +63,6 @@ add_custom_target(cargo_test
)

# Create dependency check tests
foreach (Binary codelldb${ExeSuffix} ${DylibPrefix}codelldb${DylibSuffix})
add_test(NAME dependencies:${Binary}
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/check_dependencies.py ${CMAKE_CURRENT_BINARY_DIR}/${Binary} ${AllowedDependencies})
endforeach()
add_test(NAME dependencies:adapter}
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/check_dependencies.py ${CMAKE_CURRENT_BINARY_DIR} ${AllowedDependencies}
)
10 changes: 6 additions & 4 deletions lldb/CMakeLists.txt
Expand Up @@ -3,7 +3,9 @@ add_custom_target(lldb ALL
)

# Create dependency check tests
foreach (Binary ${CheckBinaries})
add_test(NAME dependencies:${Binary}
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/check_dependencies.py ${Binary} ${AllowedDependencies})
endforeach()
add_test(NAME dependencies:lldb:bin}
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/check_dependencies.py ${CMAKE_CURRENT_BINARY_DIR}/bin ${AllowedDependencies}
)
add_test(NAME dependencies:lldb:lib}
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/check_dependencies.py ${CMAKE_CURRENT_BINARY_DIR}/lib ${AllowedDependencies}
)
61 changes: 42 additions & 19 deletions tools/check_dependencies.py
@@ -1,38 +1,33 @@
#! /usr/bin/env python3

import sys
print('version:', sys.version)
print('executable:', sys.executable)
print('path:', sys.path)

import os
import re
import subprocess
import argparse

def check(libraries):
disallowed = False
allowed_regex = re.compile(sys.argv[2], re.IGNORECASE if sys.platform.startswith('win') else 0)
def check_dependencies(libraries, wl_regex):
clean = True
for library in libraries:
if not allowed_regex.fullmatch(library):
print('{} is not on allowed list'.format(library))
disallowed = True
if disallowed:
sys.exit(1)
if not wl_regex.fullmatch(library):
print(' {} is not in the whitelist'.format(library))
clean = False
return clean

def main():
def get_dependencies(binary):
if sys.platform.startswith('linux'):
output = subprocess.check_output(['ldd', sys.argv[1]]).decode('utf8')
output = subprocess.check_output(['ldd', binary]).decode('utf8')
regex = re.compile(r'^\s+([^\s]+)', re.MULTILINE)
libraries = [match.group(1) for match in regex.finditer(output)]
check(libraries)
return libraries
elif sys.platform.startswith('darwin'):
output = subprocess.check_output(['otool', '-L', sys.argv[1]]).decode('utf8')
output = subprocess.check_output(['otool', '-L', binary]).decode('utf8')
regex = re.compile(r'^\s+([^\s]+)', re.MULTILINE)
libraries = [match.group(1) for match in regex.finditer(output)]
libraries = [os.path.basename(f) for f in libraries]
check(libraries)
return libraries
elif sys.platform.startswith('win'):
output = subprocess.check_output(['dumpbin', '/dependents', sys.argv[1]]).decode('utf8')
output = subprocess.check_output(['dumpbin', '/dependents', binary]).decode('utf8')
regex = re.compile(r'Image has the following dependencies:\s*\r\n\r\n((.+\r\n)*)\s*\r\n')
match = regex.search(output)
if not match:
Expand All @@ -41,10 +36,38 @@ def main():
regex = re.compile(r'^\s+([^\s]+)', re.MULTILINE)
libraries = [match.group(1) for match in regex.finditer(match.group(1))]
libraries = [os.path.basename(f) for f in libraries]
check(libraries)
return libraries
else:
print('Unsupported platform')
sys.exit(1)

def check_file(fpath, wl_regex):
if sys.platform.startswith('win'):
if not (fpath.endswith('.exe') or fpath.endswith('.dll')):
return True
else:
if not ('.so' in fpath or '.dylib' in fpath or (not fpath.endswith('.py') and os.access(fpath, os.X_OK))):
return True

print('Checking', fpath)
deps = get_dependencies(fpath)
return check_dependencies(deps, wl_regex)

def main():
parser = argparse.ArgumentParser()
parser.add_argument('directory')
parser.add_argument('whitelist')
args = parser.parse_args()

wl_regex = re.compile(args.whitelist, re.IGNORECASE if sys.platform.startswith('win') else 0)

clean = True
for entry in os.scandir(args.directory):
if not entry.is_dir():
clean = check_file(entry.path, wl_regex) and clean

if not clean:
sys.exit(1)

if __name__ == '__main__':
main()

0 comments on commit 0abc418

Please sign in to comment.